package com.corpgovernment.permission.service;

import com.corpgovernment.api.organization.bo.RecManagerBO;
import com.corpgovernment.api.organization.bo.SearchRecManagerRequestBO;
import com.corpgovernment.api.organization.bo.SearchRecManagerResponseBO;
import com.corpgovernment.api.organization.model.bookingrelation.UidOrgIdEntry;
import com.corpgovernment.common.entity.db.BaseEntity;
import com.corpgovernment.organization.convert.EmployeeInfoConvert;
import com.corpgovernment.organization.dataloader.db.MbOrgEmployeeLoader;
import com.corpgovernment.organization.dataloader.db.MbRoleLoader;
import com.corpgovernment.organization.dataloader.db.MbUserRoleLoader;
import com.corpgovernment.organization.entity.db.MbOrgEmployeeInfo;
import com.corpgovernment.permission.entity.db.MbRole;
import com.corpgovernment.permission.entity.db.MbUserRole;
import com.corpgovernment.permission.mapper.RoleMapper;
import com.corpgovernment.permission.mapper.UserRoleMapper;
import com.corpgovernment.supplier.common.DefExample;
import com.ctrip.corp.obt.generic.utils.CollectionUtils;
import com.ctrip.corp.obt.generic.utils.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class RoleService {

    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private MbRoleLoader mbRoleLoader;
    @Autowired
    private UserRoleMapper userRoleMapper;
    @Autowired
    private MbUserRoleLoader mbUserRoleLoader;
    @Autowired
    private MbOrgEmployeeLoader mbOrgEmployeeLoader;
    @Autowired
    private EmployeeInfoConvert employeeInfoConvert;

    public void insertOrUpdate(MbRole role) {
        if (role.getId() == null) {
            roleMapper.insertSelective(role);
        } else {
            roleMapper.updateByPrimaryKeySelective(role);
        }
    }

    public void delete(Long id) {
        Example e = new DefExample(MbRole.class);
        e.createCriteria().andEqualTo("id", id);
        MbRole record = new MbRole();
        record.setIsDeleted(true);
        roleMapper.updateByExampleSelective(record, e);
    }

    public MbRole load(Long id) {
        Example e = new DefExample(MbRole.class);
        e.createCriteria().andEqualTo("id", id);
        return roleMapper.selectOneByExample(e);
    }

    public List<MbRole> selectByParentId(Long parentId) {
        Example e = new DefExample(MbRole.class);
        e.createCriteria().andEqualTo("parentId", parentId);
        return roleMapper.selectByExample(e);
    }

    public List<MbRole> selectRoles(List<Long> id) {
        if (CollectionUtils.isEmpty(id)) {
            return Collections.emptyList();
        }
        Example e = new DefExample(MbRole.class);
        e.createCriteria().andIn("id", id);
        return roleMapper.selectByExample(e);
    }

    public List<MbRole> listCorpRoles(String corpId) {
        Example e = new DefExample(MbRole.class);
        e.createCriteria().andEqualTo("orgId", corpId).andEqualTo("isDeleted", false);
        return roleMapper.selectByExample(e);
    }

    public List<MbRole> findByUidAndOrgId(String uid, String orgId) {
        if (StringUtils.isEmpty(uid)) {
            return new ArrayList<>();
        }
        List<MbUserRole> userRoleList = userRoleMapper.findByUidAndOrgId(uid.trim(), orgId);
        if (CollectionUtils.isEmpty(userRoleList)) {
            return new ArrayList<>();
        }
        List<Long> roleIdList = userRoleList.stream().map(MbUserRole::getRoleId).collect(Collectors.toList());
        return roleMapper.findByRoleIds(roleIdList);
    }

    /**
     * 通过uid和orgId查询对应的角色id
     */
    public Map<Pair<String, String>, List<Long>>
        batchSearchUserRoleIdByUidAndOrgId(List<Pair<String, String>> uidOrgIds) {
        if (CollectionUtils.isEmpty(uidOrgIds)) {
            return Collections.emptyMap();
        }

        List<UidOrgIdEntry> uidOrgIdList = uidOrgIds.stream()
            .map(uidOrgId -> new UidOrgIdEntry(uidOrgId.getLeft(), uidOrgId.getRight())).collect(Collectors.toList());

        return userRoleMapper.batchSearchUserRoleIdByUidAndOrgId(uidOrgIdList).stream()
            .collect(Collectors.groupingBy(mbUserRole -> Pair.of(mbUserRole.getUid(), mbUserRole.getOrgId()),
                Collectors.mapping(MbUserRole::getRoleId, Collectors.toList())));
    }

    /**
     * 通过角色id查询角色名
     */
    public Map<Long, String> batchSearchRoleName(Set<Long> ids) {
        if (CollectionUtils.isEmpty(ids)){
            return Collections.emptyMap();
        }
        return roleMapper.batchSearchRoleName(ids).stream()
            .collect(Collectors.toMap(MbRole::getId, MbRole::getName, (r1, r2) -> r1));
    }

    /**
     * 查询对账管理员
     *
     * @param request
     * @return
     */
    public SearchRecManagerResponseBO searchRecManager(SearchRecManagerRequestBO request) {
        if (request == null) {
            return SearchRecManagerResponseBO.empty();
        }
        String corpId = request.getCorpId();
        List<MbRole> mbRoles = mbRoleLoader.selectRecManager(corpId);
        if (CollectionUtils.isEmpty(mbRoles)) {
            return SearchRecManagerResponseBO.empty();
        }
        List<Long> roleIds = mbRoles.stream().map(BaseEntity::getId).collect(Collectors.toList());
        List<MbUserRole> userRoles = mbUserRoleLoader.selectByRoleIds(roleIds);
        if (CollectionUtils.isEmpty(userRoles)) {
            return SearchRecManagerResponseBO.empty();
        }
        List<String> uids = userRoles.stream().map(MbUserRole::getUid).distinct().collect(Collectors.toList());
        List<MbOrgEmployeeInfo> employeeInfos = mbOrgEmployeeLoader.selectByUids(uids);
        List<RecManagerBO> recManagerBOS = employeeInfoConvert.convertToRecManger(employeeInfos);
        return SearchRecManagerResponseBO.create(recManagerBOS);
    }

    /**
     * 新查询对账管理员 根据角色id查询
     *
     * @param request
     * @return
     */
    public SearchRecManagerResponseBO newSearchRecManager(SearchRecManagerRequestBO request) {
        if (request == null) {
            return SearchRecManagerResponseBO.empty();
        }
        List<String> roleId = request.getRoleId();
        if (CollectionUtils.isEmpty(roleId)) {
            return SearchRecManagerResponseBO.empty();
        }
        List<MbRole> mbRoles = mbRoleLoader.selectByRoleIdInfo(roleId);
        if (CollectionUtils.isEmpty(mbRoles)) {
            return SearchRecManagerResponseBO.empty();
        }
        List<Long> roleIds = mbRoles.stream().map(BaseEntity::getId).collect(Collectors.toList());
        List<MbUserRole> userRoles = mbUserRoleLoader.selectByRoleIds(roleIds);
        if (CollectionUtils.isEmpty(userRoles)) {
            return SearchRecManagerResponseBO.empty();
        }
        List<String> uids = userRoles.stream().map(MbUserRole::getUid).distinct().collect(Collectors.toList());
        List<MbOrgEmployeeInfo> employeeInfos = mbOrgEmployeeLoader.selectByUids(uids);
        List<RecManagerBO> recManagerBOS = employeeInfoConvert.convertToRecManger(employeeInfos);
        return SearchRecManagerResponseBO.create(recManagerBOS);
    }
}
